package viper.main;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;

import viper.GUI.ViperGUI;

/**
 * @author Kevin Sin
 * 
 * Revision number: 1
 * Date created: 1/17/10
 * Date of Last Back-up on SVN: none
 * 
 * <p>This class is the central class that keeps track of what a user is doing
 * - logged off, in a call, setting up a call, who the callee is...
 */
public class StateManager {
	/**
	 * Singleton structure
	 */
	public final static StateManager INSTANCE = new StateManager();
	private StateManager(){
		
	}
	//--------------------------------------------------------------
	
	/**
	 * Representing the state of this user
	 */
	private enum State {
		LOGGED_OUT, NOT_IN_CALL, IN_CALL 
	}
	private State state = State.LOGGED_OUT;
	
	private void setState(State state) {
		this.state = state;
	}

	public State getState() {
		return state;
	}
	//----------------------------------------------------------------
	
	public static final int VIPER_PORT = 40052; //UDP port to use
	
	private String username; //name that is displayed
	private ArrayList<Object[]> peers; //peers online
	private ArrayList<Object[]> relays; //relays used in a call
	private Object[] calleeArray; //Object[] for callee
	
	
	/**
	 * @return - IP address in String format
	 */
	public String getIP() {
		String ip = null;
		try {
			InetAddress address = InetAddress.getLocalHost();
			ip = address.getHostAddress();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return ip;
	}
	
	/**
	 * @param username
	 * Transition from LOGGED_OUT to NOT_IN_CALL
	 */
	public void login(String username){
		setUsername(username);
		MySQLFunctions.login(getIP(), username);
		setState(State.NOT_IN_CALL);
		ViperGUI.INSTANCE.changeCard(ViperGUI.LOGGED_IN_CARD);
	}
	
	/**
	 * Transitions from any state to LOGGED_OUT
	 */
	public void logout(){
		MySQLFunctions.logout(getIP());
		setState(State.LOGGED_OUT);
		ViperGUI.INSTANCE.changeCard(ViperGUI.LOGGED_OUT_CARD);
	}
	
	/**
	 * Transition from NOT_IN_CALL to IN_CALL
	 */
	public void makeCall(){
		ViperGUI.INSTANCE.changeCard(ViperGUI.IN_CALL_CARD);
	}
	
	/**
	 * @param peerIndex which peer the user wants to talk to
	 * Transition when setting up a call after picking somebody to call.
	 */
	public void setupCall(int peerIndex){
		setCalleeArray(peers.get(peerIndex));
		ViperGUI.INSTANCE.changeCard(ViperGUI.CALL_SENDER_SETUP_CARD);
	}
	
	/**
	 * Transition from IN_CALL to NOT_IN_CALL
	 */
	public void endCall(){
		ViperGUI.INSTANCE.changeCard(ViperGUI.LOGGED_IN_CARD);
	}

	/**
	 * @param username
	 * Setter method for username
	 */
	public void setUsername(String username) {
		this.username = username;
	}

	/**
	 * @return
	 * Getter method for username
	 */
	public String getUsername() {
		return username;
	}
	
	/**
	 * @return
	 * Getter method for peers
	 */
	public ArrayList<Object[]> getPeers() {
		return peers;
	}

	/**
	 * updates the peers variable
	 * make sure you are not added yourself
	 */
	public void updatePeers() {
		ArrayList<Object[]> users = MySQLFunctions.getCurrentUsers();
		for(Object[] userArray : users)
    	{
			if(((String)userArray[0]).equals(getIP()))
			{
				users.remove(userArray);
				break;
			}
    	}
		peers = users;
	}	

	/**
	 * @param calleeArray
	 * Setter method for calleeArray
	 */
	public void setCalleeArray(Object[] calleeArray) {
		this.calleeArray = calleeArray;
	}

	/**
	 * @return
	 * Getter method for calleeArray
	 */
	public Object[] getCalleeArray() {
		return calleeArray;
	}

	/**
	 * @param
	 * Setter method for relays
	 */
	public void setRelays(ArrayList<Object[]> relays) {
		this.relays = relays;
	}

	/**
	 * @return
	 * Getter method for relays
	 */
	public ArrayList<Object[]> getRelays() {
		return relays;
	}
}
